VSWI – Vegetation Supply Water Index
VSWI is a vegetation water-stress index that combines greenness (NDVI) and surface temperature (LST) to indicate how well vegetation is supplied with water. Cool, green canopies indicate good water supply; hot, low-NDVI canopies indicate water stress or drought.
What does VSWI measure?
VSWI links the spectral information of vegetation (NDVI) with land-surface temperature derived from thermal infrared bands. Under water stress, transpiration decreases and canopy temperature rises, while NDVI may still be relatively high. VSWI captures this combined signal.
- Monitoring crop water stress at field to regional scale.
- Drought assessment over agricultural and natural vegetation.
- Supporting irrigation management and water-use efficiency studies.
- Providing a combined NDVI–LST feature for eco-hydrological modelling.
Note: several VSWI formulations exist in the literature (often related to TVDI or NDVI–LST space). The expression below is an example that normalises both NDVI and LST.
VSWI formula (example)
NDVIn = (NDVI - NDVImin) / (NDVImax - NDVImin)
Tsn = (Ts - Tsmin) / (Tsmax - Tsmin)
VSWI = NDVIn · (1 - Tsn)
In this example, high VSWI corresponds to green, relatively cool canopies (good water supply), while low VSWI indicates hot and/or low-NDVI conditions (water stress).
You can adapt this formulation to match your reference (e.g. different normalisation schemes, or using 1 − TVDI).
Required inputs
Spectral indices & thermal data
| Component | Source |
|---|---|
| NDVI | RED & NIR bands (e.g. from Landsat, Sentinel-2) |
| LST / surface temperature | Thermal band (e.g. Landsat TIR) or LST product |
| NDVImin/max | Derived from NDVI range over ROI / season |
| Tsmin/max | Derived from LST range over ROI / season |
Tip: NDVI and LST should be computed from cloud-free, atmospherically corrected imagery for consistent VSWI results.
Interpreting VSWI (example)
| VSWI range | Interpretation |
|---|---|
| High (close to 1) | Green & cool canopy – low water stress |
| Medium | Moderate water availability / mild stress |
| Low (close to 0) | Hot and/or low NDVI – strong water stress / drought |
| Near zero or negative | Bare soil, non-vegetated, or noisy pixels |
Actual thresholds depend on crop type, climate and the period used to derive min/max NDVI and LST. Always calibrate with field data when possible.
Using VSWI in Google Earth Engine (example with Landsat 8/9)
- Compute NDVI from RED and NIR reflectance.
- Obtain surface temperature (Ts) from the thermal band or LST product.
- Derive NDVImin/max and Tsmin/max over your ROI / period.
- Compute normalised NDVI and Ts, then VSWI = NDVIn · (1 − Tsn).
// VSWI – Vegetation Supply Water Index example (Landsat 8/9) in Google Earth Engine
var roi = /* your geometry here */;
// Landsat 8/9 L2 collection (surface reflectance + ST_B10)
var l8 = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')
.filterBounds(roi)
.filterDate('2023-04-01', '2023-09-30')
.filter(ee.Filter.lt('CLOUD_COVER', 20));
// Scale factors from USGS documentation (example)
function scaleL8(img) {
var optical = img.select(['SR_B.']).multiply(0.0000275).add(-0.2);
var thermal = img.select('ST_B10').multiply(0.00341802).add(149.0); // Kelvin
return img.addBands(optical, null, true)
.addBands(thermal.rename('Ts'));
}
l8 = l8.map(scaleL8);
// Median composite
var img = l8.median();
// NDVI
var nir = img.select('SR_B5');
var red = img.select('SR_B4');
var ndvi = nir.subtract(red).divide(nir.add(red)).rename('NDVI');
// Surface temperature (Kelvin) & convert to Celsius if needed
var ts = img.select('Ts'); // or ts.subtract(273.15) for °C
// Derive min/max over ROI for NDVI and Ts
var ndviStats = ndvi.reduceRegion({
reducer: ee.Reducer.minMax(),
geometry: roi,
scale: 30,
maxPixels: 1e7
});
var tsStats = ts.reduceRegion({
reducer: ee.Reducer.minMax(),
geometry: roi,
scale: 30,
maxPixels: 1e7
});
var ndviMin = ee.Number(ndviStats.get('NDVI_min'));
var ndviMax = ee.Number(ndviStats.get('NDVI_max'));
var tsMin = ee.Number(tsStats.get('Ts_min'));
var tsMax = ee.Number(tsStats.get('Ts_max'));
// Normalised NDVI and Ts
var ndvi_n = ndvi.subtract(ndviMin)
.divide(ndviMax.subtract(ndviMin).add(1e-6));
var ts_n = ts.subtract(tsMin)
.divide(tsMax.subtract(tsMin).add(1e-6));
// VSWI = NDVI_n * (1 - Ts_n)
var vswi = ndvi_n.multiply(ee.Image(1).subtract(ts_n)).rename('VSWI');
// Visualisation
Map.centerObject(roi, 8);
Map.addLayer(vswi, {
min: 0.0, max: 1.0,
palette: ['#7f1d1d','#f97316','#eab308','#22c55e','#16a34a']
}, 'VSWI - Vegetation Supply Water Index');
// Optional export
Export.image.toDrive({
image: vswi,
description: 'VSWI_Landsat8_example',
region: roi,
scale: 30,
maxPixels: 1e13
});
Important: treat this VSWI expression as a practical example. If you use a specific published VSWI / TVDI-based formula, replace the equations above with your exact definition while keeping this HTML layout.